#include "AddMask.h"
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osg/Material>
#include <math.h>
#include <osgDB/WriteFile>

int AddMask::process()
{
	osgDB::DirectoryContents dirNames = osgDB::getDirectoryContents(_input_dir);
	osgDB::DirectoryContents::iterator iter = dirNames.begin();
	osg::Group* root = new osg::Group();
	while (iter != dirNames.end()) {
		std::string dir = *iter;
		if (dir.find(".") != std::string::npos) {
			iter++;
			continue;
		}
		_process_sub_dir(dir);
		iter++;

	}
	return 0;
}



int AddMask::handle(const osgEarth::Config* cfg)
{
	if (cfg->child_ptr("input")) {
		this->_input_dir = cfg->child_ptr("input")->value();
	}
	if (cfg->child_ptr("output")) {
		this->_output_dir = cfg->child_ptr("output")->value();
	}
	if (this->_input_dir.size() < 1 || this->_output_dir.size() < 1) return -1;
	
	return this->process();
}

void _processGeometry(osg::Geometry* geom, int intcolor) {

	if (!geom)
	{
		return;
	}

	//iidd = 0b110000011100000001;
	int b = (intcolor >> 16) % 256;
	int g = (intcolor >> 8) % 256;
	int r = intcolor % 256;
	//osg::Geometry* geom =  geode->getDrawable(0)->asGeometry();
	osg::StateSet* pss = geom->getOrCreateStateSet();
	//osg::Material* mat = new osg::Material();
	//mat->setColorMode(osg::Material::ColorMode::EMISSION);
	//mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0.0, 0.0, 0.0, 1));
	//mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0.0, 0.0, 0.0, 1));
	//mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0.0, 0.0, 0.0, 1));
	//mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4((float)r / 255.0, (float)g / 255.0, (float)b / 255.0, 1.0f));
	//pss->setAttribute(mat, osg::StateAttribute::ON);
	//pss->setTextureAttributeAndModes(0, osg::StateAttribute::ON);

	//pss->setTextureAttributeAndModes(0, 0, osg::StateAttribute::OFF);
	//pss->removeTextureAttribute(0, 0);
	//pss->removeTextureMode(0, osg::StateAttribute::OFF);
	pss->clear();
	pss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
	pss->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF);
	geom->setTexCoordArray(0, 0);
	osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
	colors->push_back(osg::Vec4((float)r / 255.0, (float)g / 255.0, (float)b / 255.0, 1.0f));
	geom->setColorArray(colors);
	geom->setColorBinding(osg::Geometry::BIND_OVERALL);
	
}

#include <osg/PagedLOD>
class FindGeometryVistor : public osg::NodeVisitor
{
public:
	FindGeometryVistor() :
		osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
		_intcolor(0)
	{
	}

	virtual void apply(osg::Geometry& node)
	{
		_processGeometry(&node, _intcolor);
		traverse(node);
	}
	virtual void apply(osg::PagedLOD& node)
	{
		node.setDatabasePath("");
		traverse(node);
	}
	unsigned int _intcolor;
};

#include <QString>
int AddMask::_process_sub_dir(std::string subdir)
{
	std::string abs_sub_dir = _input_dir + "/" + subdir + "/";
	osgDB::DirectoryContents osgbfiles = osgDB::getDirectoryContents(abs_sub_dir);
	osgDB::DirectoryContents::iterator iter = osgbfiles.begin();
	
	int intcolor = QString::fromStdString(subdir).toInt();
	//int b = (intcolor >> 16) % 256;
	//int g = (intcolor >> 8) % 256;
	//int r = intcolor % 256;
	
	//osg::Group* root = new osg::Group();
	
	
	std::string outpath = this->_output_dir + "/" + subdir + "/";
	while (iter != osgbfiles.end()) {
		std::string osgf = *iter;
		if (osgf.find(".") == 0) {
			iter++;
			continue;
		}


		
		_process_file(intcolor, abs_sub_dir, osgf, outpath);

		iter++;
	}
	return 0;
}

void AddMask::_process_file(int intcolor, std::string inpath, std::string osgf, std::string outpath)
{
	auto visitor = new	FindGeometryVistor();
	visitor->_intcolor = intcolor;
	std::string osgbFile = inpath + "/" + osgf;
	osg::ref_ptr<osg::Node> c = osgDB::readNodeFile(osgbFile);
	if (c)
	{
		c->accept(*visitor);
		osgDB::makeDirectory(outpath);
		outpath = outpath + "/" + osgf;
		osgDB::writeNodeFile(*c, outpath);
		std::cout << "PROCESS:" << osgbFile;
	}
}
